/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package base;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

/**
 *
 * @author Tue
 */
public class KN {
    private Hashtable<String, KNNode> NATTable;
    private int id;

    private volatile static KN singleton;
    
    public KN(){
        NATTable = new Hashtable<String, KNNode>();
        id = 0;
    }
    public static KN getInstance(){
        if(singleton == null){
            synchronized(KN.class){
                if(singleton == null){
                    singleton = new KN();
                }
            }
        }
        return singleton;
    }
    public boolean addKNNode(String nodeName){
        if(!NATTable.containsKey(nodeName)){
            KNNode newNode = new KNNode(nodeName);
            NATTable.put(nodeName, newNode);
            return true;
        }
        return false;
    }

    public boolean addKNNode(KNNode node){
        if(!NATTable.containsKey(node.getName())){
            NATTable.put(node.getName(), node);
            return true;
        }
        return false;
    }
    public int addKNNode(List<String> nodes){
        int addedNode = 0;
        for(String node : nodes){
            if(addKNNode(node)) addedNode++;
        }
        return addedNode;
    }
    public boolean addKNLink(String linkName, int sign, KNNode srcNode, String desNodeName, String desHostAddress){
        KNLink link = new KNLink(linkName, desHostAddress, desNodeName, sign);
        if(!srcNode.getAllLinks().contains(link)){
            srcNode.addLink(link);
            return true;
        }
        return false;
    }
    
    public void delKNNode(String name){
        
    }
    public void delKNLink(String srcNode, String desNode, String linkName){
        
    }
    public KNNode getKNNode(String name){
        return NATTable.get(name);
    }

    public int getNumberNodes(){
        return NATTable.size();
    }
    public ArrayList<KNNode> getAllKNNodes(){
        ArrayList<KNNode> listNode = new ArrayList<KNNode>(NATTable.values());
        return listNode;
    }
    public ArrayList<KNLink> getAllLinks(String nodeName){
        return getKNNode(nodeName).getAllLinks();
    }
    public ArrayList<KNLink> getAllLinks(KNNode node){
        return node.getAllLinks();
    }
    public ArrayList<KNLink> getLinks(String nodeName, int sign){
        KNNode node = NATTable.get(nodeName);
        return node.getLinks(sign);
    }
    public ArrayList<KNLink> getLinks(KNNode node, int sign){
        return node.getLinks(sign);
    }
    
    public ArrayList<KNLink> getOutgoingLinks(String nodeName){
        return getLinks(nodeName, 1);
    }
    public ArrayList<KNLink> getIncommingLinks(String nodeName){
        return getLinks(nodeName, -1);
    }
    public void renameLink(String srcNode, String desNode, String oldName, String newName) {
        System.out.println("RENAME LINK: " + oldName + " TO " + newName);
        ArrayList<KNLink> allLinks = getAllLinks(srcNode);
        for( KNLink link : allLinks) {
            if(link.getName().equals(oldName) && link.getDesNodeName().equals(desNode)) {
                link.setName(newName);
                System.out.println("RENAME DONE!");
            }
        }
        allLinks = getAllLinks(desNode);
        for( KNLink link : allLinks) {
            if(link.getName().equals(oldName) && link.getDesNodeName().equals(srcNode)) {
                link.setName(newName);
                System.out.println("RENAME DONE!");
            }
        }

    }
    public ArrayList<String> getAllNeighborOf(String nodeName){
        ArrayList<KNLink> linkTable = getAllLinks(nodeName);
        ArrayList<String> result = new ArrayList<String>();
        for(KNLink link : linkTable){
            result.add(link.getDesNodeName());
        }
        return result;
    }
    /**
     * Remove all node and link in kn
     */
    public void flush(){
        for (KNNode node : NATTable.values()){
            node.removeAllLinks();
        }
        NATTable.clear();
    }

    @Override
    public String toString(){
        String result = "";
        result += "So node: " + NATTable.keySet().size() + " ";
        result += NATTable.keySet() + "%%";
        result += NATTable.values();
        //result += " " + LATTable.values();
        return result;
    }

}
